package service

import (
	"context"
	"dy/internal/api/store"
	"dy/internal/models"
	"dy/pkg/util"
	"errors"
)

type FavoriteSrv interface {
	Action(ctx context.Context, param map[string]interface{}) error
	List(ctx context.Context, userId int) ([]map[string]interface{}, error)
}

type favoriteService struct {
	store store.Factory
}

func (u *favoriteService) Action(ctx context.Context, param map[string]interface{}) error {
	var dyLikeRelation *models.DyLikeRelation
	err := util.StructTo(&param, &dyLikeRelation)
	if err != nil {
		return err
	}

	if param["action_type"].(int) == 1 {
		_, flag, err := u.store.Favorite().Get(ctx, dyLikeRelation)
		if err != nil {
			return err
		}
		if flag == true {
			return nil
		}

		_, err = u.store.Favorite().Create(ctx, dyLikeRelation)
		if err != nil {
			return err
		}
	} else if param["action_type"].(int) == 2 {
		likeRelation, flag, err := u.store.Favorite().Get(ctx, dyLikeRelation)
		if err != nil {
			return err
		}
		if flag == false {
			return nil
		}

		_, err = u.store.Favorite().Del(ctx, likeRelation.Id)
		if err != nil {
			return err
		}
	} else {
		return errors.New("wrong action_type")
	}

	return nil
}

func (u *favoriteService) List(ctx context.Context, userId int) ([]map[string]interface{}, error) {
	search := map[string]interface{}{}
	if userId != 0 {
		search["user_id"] = userId
	}

	list, _, err := u.store.Favorite().Find(ctx, search, "add_time", "")
	if err != nil {
		return nil, err
	}
	result := make([]map[string]interface{}, 0)

	for _, element := range list {
		dyVideo, flag, err := u.store.Video().Get(ctx, &models.DyVideo{Id: element.VideoId})
		if !flag {
			return nil, errors.New("the video is not exist")
		}
		if err != nil {
			return nil, err
		}

		dyUser, flag, err := u.store.User().Get(ctx, &models.DyUser{Id: dyVideo.AuthorId})
		if !flag {
			return nil, errors.New("the author is not exist")
		}
		if err != nil {
			return nil, err
		}

		_, followCount, err := u.store.Relation().Find(ctx, map[string]interface{}{"user_id": dyUser.Id}, "add_time", "")
		if err != nil {
			return nil, err
		}
		_, followerCount, err := u.store.Relation().Find(ctx, map[string]interface{}{"follow_id": dyUser.Id}, "add_time", "")
		if err != nil {
			return nil, err
		}
		_, isFollow, err := u.store.Relation().Get(ctx, &models.DyUserRelation{UserId: userId, FollowId: dyUser.Id})
		if err != nil {
			return nil, err
		}

		user := map[string]interface{}{
			"id":             dyUser.Id,
			"name":           dyUser.Name,
			"follow_count":   followCount,
			"follower_count": followerCount,
			"is_follow":      isFollow,
		}

		_, favoriteCount, err := u.store.Favorite().Find(ctx, map[string]interface{}{"video_id": dyVideo.Id}, "add_time", "")
		if err != nil {
			return nil, err
		}
		_, commentCount, err := u.store.Comment().Find(ctx, map[string]interface{}{"video_id": dyVideo.Id}, "add_time", "")
		if err != nil {
			return nil, err
		}
		_, isFavorite, err := u.store.Favorite().Get(ctx, &models.DyLikeRelation{UserId: userId, VideoId: dyVideo.Id})
		if !flag {
			return nil, errors.New("the author is not exist")
		}
		if err != nil {
			return nil, err
		}

		video := map[string]interface{}{
			"id":             dyVideo.Id,
			"author":         user,
			"play_url":       dyVideo.PlayUrl,
			"cover_url":      dyVideo.CoverUrl,
			"favorite_count": favoriteCount,
			"comment_count":  commentCount,
			"is_favorite":    isFavorite,
			"title":          dyVideo.Title,
		}

		result = append(result, video)
	}

	return result, nil
}

func NewFavoriteService(s *service) FavoriteSrv {
	return &favoriteService{
		store: s.store,
	}
}
